classdef jwlong_dsox2004a_class
    % 修改时间： 20240620_08h18m14s
    %     instrreset
    % 1、执行连接函数
    % oscilloscope=sjwlong_dsox2004a_class.Conect( ...
    %     'keysight','TCPIP0::192.168.100.10::5025::SOCKET');
% (Access = public)
    properties 
        obj % 连接仪器的对象       
        idn % 保存仪器的编号  
    end
    
    methods
        function jwl = jwlong_dsox2004a_class()
            %  构造此类的实例
        end
    end
    
    methods (Static)%不需要创建对象，也可以直接调用的函数
        % 利用connect函数，创建对象，同时建立仪器连接
        function jwl = Conect(company,visa_address)
            jwl = jwlong_dsox2004a_class();
            jwl.obj=visa(company,visa_address);
            %读取曲线时，单次传输最大字符数
            MAXPOINT = 62500;
            % 数据头有10位,末尾有个\n,每个数据13位,数据间隔','占1位
            % +20为保留的余量
            jwl.obj.InputBufferSize = 11+14*MAXPOINT+20;
            fopen(jwl.obj);
            jwl.idn=jwl.SendAndReadMessage('*IDN?');
        end            
    end
    
    
    methods % 创建对象后才可以调用的函数
        function SendMessage(jwl,command)
            % 发送命令
            fprintf(jwl.obj,command);
        end
        
        function y=SendAndReadMessage(jwl,query)
            % 发送并且读取字符串信息
            fprintf(jwl.obj,query);
            y=fscanf(jwl.obj);
        end
        
        function num=SendAndReadNumber(jwl,query)
            % 发送并且读取字符串信息
            fprintf(jwl.obj,query);
            str=fscanf(jwl.obj);
            num=str2double(str);
        end
                
        function date=askCalibrationDate(jwl)
            % 仪器校准日期
            date=jwl.SendAndReadMessage(':CALibrate:DATE?');
        end
        
        function SampleRate=askSampleRate(jwl)
           SampleRate=jwl.SendAndReadMessage('ACQuire:SRATe?');
        end
        
        function setReset(jwl)
            % 重置仪器
            jwl.SendMessage("*RST");
        end
            
        function setClear(jwl)
            % 清除所有事件寄存器和所有队列
            jwl.SendMessage("*CLS");
        end   
        
        function setAutocale(jwl)
            % 自动设置
            jwl.SendMessage(":AUToscale");
        end
        
        function openWaveGen(jwl)  
            % 打开函数发生器
            jwl.SendMessage(":WGEN:OUTPut ON");%{{1 | ON} | {0 | OFF}
        end   
        
        function CloseWaveGen(jwl)
            % 关闭函数发生器
            jwl.SendMessage(":WGEN:OUTPut OFF");%{{1 | ON} | {0 | OFF}
        end  
        
        function setWaveGenSin(jwl,freq_Hz,Mag_V)
            % 设置函数发生器，正弦波，并且打开
            % SINusoid | SQUare | RAMP | PULSe | NOISe | DC
            jwl.SendMessage(":WGEN:FUNCtion SINusoid");
            jwl.SendMessage([':WGEN:FREQuency ',num2str(freq_Hz)]);
            jwl.SendMessage([':WGEN:VOLTage ',num2str(Mag_V)]);
            jwl.openWaveGen();
        end
        
        function setWaveGenSqu(jwl,Freq_Hz,Mag_V,OFFSet_V,DCYCle_percent)
            % 设置函数发生器，方波，并且打开
            % SINusoid | SQUare | RAMP | PULSe | NOISe | DC
            jwl.SendMessage(":WGEN:FUNCtion SQUare");
            jwl.SendMessage([':WGEN:FREQuency ',num2str(Freq_Hz)]);
            jwl.SendMessage([':WGEN:VOLTage ',num2str(Mag_V)]);
            jwl.SendMessage([':WGEN:VOLTage:OFFSet ',num2str(OFFSet_V)]);
            jwl.SendMessage([':WGEN:FUNCtion:SQUare:DCYCle ',num2str(DCYCle_percent)]);
            jwl.openWaveGen();
        end
        
        function setWaveGenRamp(jwl,Freq_Hz,Mag_V,OFFSet_V,DCYCle_percent)
            % 设置函数发生器，锯齿波，并且打开
            % SINusoid | SQUare | RAMP | PULSe | NOISe | DC
            jwl.SendMessage(":WGEN:FUNCtion RAMP");
            jwl.SendMessage([':WGEN:FREQuency ',num2str(Freq_Hz)]);
            jwl.SendMessage([':WGEN:VOLTage ',num2str(Mag_V)]);
            jwl.SendMessage([':WGEN:VOLTage:OFFSet ',num2str(OFFSet_V)]);
            jwl.SendMessage([':WGEN:FUNCtion:SQUare:DCYCle ',num2str(DCYCle_percent)]);
            jwl.openWaveGen();
        end
        
        function setWaveGenPulse(jwl,Freq_Hz,Mag_V,OFFSet_V,WIDTh_s)
            % 设置函数发生器，脉冲波，并且打开
            % SINusoid | SQUare | RAMP | PULSe | NOISe | DC
            jwl.SendMessage(":WGEN:FUNCtion PULSe");
            jwl.SendMessage([':WGEN:FREQuency ',num2str(Freq_Hz)]);
            jwl.SendMessage([':WGEN:VOLTage ',num2str(Mag_V)]);
            jwl.SendMessage([':WGEN:VOLTage:OFFSet ',num2str(OFFSet_V)]);
            jwl.SendMessage([':WGEN:FUNCtion:PULSe:WIDTh ',num2str(WIDTh_s)]);
            jwl.openWaveGen();
        end
        
        function openCHANnel(jwl,CHANnel,attenuation)
            % 打开通道 1~4，并且设置探头倍数
            jwl.SendMessage([':CHANnel',num2str(CHANnel),':DISPlay ON']);           
            jwl.SendMessage([':CHANnel',num2str(CHANnel),':PROBe ',num2str(attenuation)]);
        end
               
        function closeCHANnel(jwl,CHANnel)
            % 关闭通道 1~4
            jwl.SendMessage([':CHANnel',num2str(CHANnel),':DISPlay OFF']);
        end
        
        %% 时间相关
        function setTimeReference(jwl,REFerenceMode)
            TYPE={'LEFT';'CENTer';'RIGHt'};
            jwl.SendMessage([':TIMebase:REFerence ',char(TYPE(REFerenceMode))]);
        end
        
        function setTimePosition(jwl,PositionTime)
            jwl.SendMessage([':TIMebase:POSition ',num2str(PositionTime)]);
        end
        
        
        function setTimeScale(jwl,SCALe)
            jwl.SendMessage([':TIMebase:SCALe ',num2str(SCALe)]);
        end
        
        
       %% 数学计算            
        function setMathSource1(jwl,CHANnel)
            % 设置计算来源
            CH={'CHANnel1';'CHANnel2';'CHANnel3';'CHANnel4';'GOFT';};
            jwl.SendMessage([':FUNCtion:SOURce1 ',char(CH(CHANnel))]);
        end
        
        
        function setMathSource2(jwl,CHANnel)
            % 设置计算来源
            CH={'CHANnel1';'CHANnel2';'CHANnel3';'CHANnel4';'GOFT';};
            jwl.SendMessage([':FUNCtion:SOURce2 ',char(CH(CHANnel))]);
        end
        
        function openMathFFT(jwl,CHANnel,FreqCenter_Hz,FreqSpan_Hz)
            % 打开数学计算
            jwl.SendMessage(':FUNCtion:DISPlay ON');
            % 打开FFT算子
            jwl.SendMessage(':FUNCtion:OPERation FFT');
            jwl.setMathSource1(CHANnel);
            % 设置FFT中心频率
            jwl.SendMessage([':FUNCtion:FFT:CENTer ',num2str(FreqCenter_Hz)]);
            % 设置FFT带宽
            jwl.SendMessage([':FUNCtion:FFT:SPAN ',num2str(FreqSpan_Hz)]);            
        end
        
        function setMathFFTwindow(jwl,typeN)
            % 设置窗口类型
            Window={'HANNing';'FLATtop';'RECTangular';'BHARris'};     
            % HANNing - 适用于频率分辨和一般用途。它适用于分辨两个相近的频率或进行频率测量。这是默认窗口。
            % FLATtop - 最适合对频率峰值进行精确的振幅测量。
            % RECTangular - 适用于瞬态信号以及时间记录中存在整数周期的信号。
            % BHARris（布莱克曼-哈里斯）--与矩形窗口相比，时间分辨率降低，
            % 但由于次叶较低（提供最小的频谱泄漏），它提高了检测较小脉冲的能力。                     
            jwl.SendMessage([':FUNCtion:FFT:WINDow ',char(Window(typeN))]);
        end      
        
        function setMathScale(jwl,Scale_V,Offset_V)
            % 设置刻度类型 {DECibel | VRMS}
            jwl.SendMessage(':FUNCtion:FFT:VTYPe DECibel');%dB
            % 设置MATH的Y轴刻度 
            jwl.SendMessage([':FUNCtion:SCALe ',num2str(Scale_V)]);
            jwl.SendMessage([':FUNCtion:REFerence ',num2str(Offset_V)]);
        end
        
        function closeMath(jwl)
            % 关闭数学计算
            jwl.SendMessage(':FUNCtion:DISPlay OFF');
        end

        function setScale(jwl,CHANnel,Scale_V,Offset_V)
            % 设置Y轴刻度                    
            jwl.SendMessage([':CHANnel',num2str(CHANnel),':SCALe ',num2str(Scale_V)]);
            jwl.SendMessage([':CHANnel',num2str(CHANnel),':OFFSet ',num2str(Offset_V)]);
        end
        
        
       
        %% 触发相关                
        function setTrigerModeEege(jwl,CHANnelN,typeN,LEVel)
            % 设置边缘触发模式
            jwl.SendMessage(':TRIGger:MODE EDGE');   
            % 设置触发通道
            CH={'CHANnel1';'CHANnel2';'CHANnel3';'CHANnel4';'EXTernal';'LINE';'WGEN';};
            jwl.SendMessage([':TRIGger:EDGE:SOURce ',char(CH(CHANnelN))]);
            % 设置边缘类型
            type={'NEGative';'POSitive';'EITHer';'ALTernate'};
            jwl.SendMessage([':TRIGger:EDGE:SLOPe ',char(type(typeN))]); 
            % 设置触发电平
            jwl.SendMessage([':TRIGger:EDGE:LEVel ',num2str(LEVel)]);
        end
                
             
        
        
        %% 曲线获取
        function [data,point]=readTrace(jwl,CHANnelN)
            CH={'CHANnel1';'CHANnel2';'CHANnel3';'CHANnel4';'FUNCtion';'MATH'};
            jwl.SendMessage([':WAVeform:SOURce ',char(CH(CHANnelN))]);      
            % 读取字符串信息           
            jwl.SendMessage(":WAVeform:POINts NORMal");
            jwl.SendMessage(":WAVeform:FORMat ASCii");%WORD ASCii
            result = jwl.SendAndReadMessage(':WAVeform:DATA?');
            % 前11位：#800874999            
            % 之后的 874999 位为有效数据，每个数据用逗号隔开
            data_result_str=result(11:end-1);
            data=str2double(split(data_result_str,',',1));
            point=jwl.SendAndReadNumber(':WAVeform:POINts?');
%             data_byte=str2double(result(3:10));
%             fprintf('byte=%d,date=%d',data_byte,size(data_result_str,2));

        end
        
        %% 通道测试
        function measeCHANnel(jwl,CHANnelN)
            % 选择读取通道
            CH={'CHANnel1';'CHANnel2';'CHANnel3';'CHANnel4';'FUNCtion';'MATH'};
            jwl.SendMessage([':MEASure:SOURce ',char(CH(CHANnelN))]);           
        end   
        
        function [Xmax,Ymax]=measeCHANnelMax(jwl,CHANnelN)
            % 测量通道最大值,以及对应的X位置
            jwl.measeCHANnel(CHANnelN);
            Xmax=jwl.SendAndReadMessage(':MEASure:XMAX?'); 
            Ymax=jwl.SendAndReadMessage(':MEASure:VMAX?');            
        end
        
        function [Xmin,Ymin]=measeCHANnelMin(jwl,CHANnelN)
            % 测量通道最小值,以及对应的X位置
            jwl.measeCHANnel(CHANnelN);
            Xmin=jwl.SendAndReadMessage(':MEASure:XMIN?'); 
            Ymin=jwl.SendAndReadMessage(':MEASure:VMIN?');            
        end               
        
        %% 平均
        function openAverage(jwl,Count)
            % 打开平均，并且设置平均次数
            jwl.SendMessage(':MTESt:AVERage ON'); 
            jwl.SendMessage([':MTESt:AVERage:COUNt',char(num2str(Count))]); 
        end

        function closeAverage(jwl)
            % 关闭平均
            jwl.SendMessage(':MTESt:AVERage OFF');             
        end
        
    end
end

